package com.htht.smartschool.util.redis;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

import com.htht.smartschool.util.system.ConfigUtil;

public class RedisUtil {  
	
	private RedisUtil() {}  
	
	private static final RedisUtil single = new RedisUtil();  
	private  ShardedJedisPool pool = null;
	
	public ShardedJedis jedis = null;
	
	public static RedisUtil getInstance() {  
		return single;  
    }
	/**
     * 构建redis连接池
     * 
     * @param ip
     * @param port
     * @return JedisPool
     */
	public ShardedJedisPool setConfigRedis(String host,Integer port,String pass){
		if (pool == null) {
			List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
			JedisShardInfo si = new JedisShardInfo(host, port);
			si.setPassword(pass);
			si.setTimeout(10000);
			shards.add(si);
            JedisPoolConfig config = new JedisPoolConfig();
            //控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；
            //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
            config.setMaxTotal(1000);
            //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
            config.setMaxIdle(5);
            //表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
            config.setMaxWaitMillis(1000 * 1000);
            pool = new ShardedJedisPool(config,shards);
        }
        return pool;
	}
	/**
	 * 重置redis
	 */
	private void resetRedis() {
		if (this.jedis == null) {
			setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
		}
	}
    /**
     * 获取数据
     * @param key
     * @return
     */
	public String getString(String key){
		String value = null;
        try {
            pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
        } finally {
            //返还到连接池
        	pool.returnResource(jedis);
        }
        
        return value;
	}
	public boolean setHashKeyValue(String key, String field, String value) {
		try {
			pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));jedis = pool.getResource();
			jedis.hset(key, field, value);
			return true;
		} catch (Exception e) {
			//释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
		} finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
		return false;
	}
	public Set<String> getHashKeys(String key) {
		Set<String> set = null;
		try {
			pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
			set = jedis.hkeys(key);
		} catch (Exception e) {
			//释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
		} finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
		return set;
	}
	public String getHashKeyValue(String key, String fieid) {
		String value = null;
		try {
			pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
			value = jedis.hget(key, fieid);
		}  catch (Exception e) {
			//释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
		} finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
		return value;
	}
	public boolean setHashKeyValueByte(String key, String fieid, byte[] value) {
		try {
			pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));jedis = pool.getResource();
			jedis.hset(key.getBytes(), fieid.getBytes(), value);
			return true;
		} catch (Exception e) {
			//释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
		} finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
		return false;
	}
	public Set<byte[]> getHashKeysByte(String key) {
		Set<byte[]> set = null;
		try {
			pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
			set = jedis.hkeys(key.getBytes());
		} catch (Exception e) {
			//释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
		} finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
		return set;
	}
	public byte[] getHashKeyValueBtye(String key, String fieid) {
		byte[] value = null;
		try {
			pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
			value = jedis.hget(key.getBytes(), fieid.getBytes());
		}  catch (Exception e) {
			//释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
		} finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
		return value;
	}

	public boolean delHashKeyValue(String key, String fieid) {
		try {
			pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
			jedis.hdel(key, fieid);
			return true;
		} catch (Exception e) {
			//释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
		} finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
		return false;
	}
	/**
	 * 添加数据
	 * @param key
	 * @param value
	 */
	public String setString(String key,String value){
		String status = null;
        try {
            pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
            status = jedis.set(key,value);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
        } finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
        return status;
	}
	public String setString(String key,int seconds,String value){
		String status = null;
        try {
        	seconds = seconds == 0 ? 48*60*60 : seconds;
            pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
            status = jedis.setex(key, seconds, value);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
        } finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
        return status;
	}
	public Set<String> getkeys(String key){
		Set<String> status = null;
        try {
            pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
            status = jedis.keys(key+"*");
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
        } finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
        return status;
	}
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public String setMap(String key,Map value){
		String status = null;
        try {
            pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
            status = jedis.hmset(key,value);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
        } finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
        return status;
	}
	@SuppressWarnings("rawtypes")
	public List getMap(String key, final String... fields){
		List value = null;
        try {
            pool = setConfigRedis(ConfigUtil.getProperty("redis","host"),Integer.parseInt(ConfigUtil.getProperty("redis","port")),ConfigUtil.getProperty("redis","pass"));
    		jedis = pool.getResource();
            value = jedis.hmget(key, fields);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            resetRedis();
            e.printStackTrace();
        } finally {
            //返还到连接池
           pool.returnResource(jedis);
        }
        
        return value;
	}
}  
